package toOffer;

/**
 * @author YuanAo
 * @date 2024/7/18 15:08
 * @description 最小栈
 */

import java.util.*;

/**
 * 请你设计一个 最小栈 。它提供 push ，pop ，top 操作，并能在常数时间内检索到最小元素的栈。
 * <p>
 * 实现 MinStack 类:
 * <p>
 * MinStack() 初始化堆栈对象。
 * void push(int val) 将元素val推入堆栈。
 * void pop() 删除堆栈顶部的元素。
 * int top() 获取堆栈顶部的元素。
 * int getMin() 获取堆栈中的最小元素。
 * 示例 1:
 * <p>
 * 输入：
 * ["MinStack","push","push","push","getMin","pop","top","getMin"]
 * [[],[-2],[2],[-3],[],[],[],[]]
 * <p>
 * 输出：
 * [null,null,null,null,-3,null,2,-2]
 * <p>
 * 解释：
 * MinStack minStack = new MinStack();
 * minStack.push(-2);
 * minStack.push(2);
 * minStack.push(-3);
 * minStack.getMin();   --> 返回 -3.
 * minStack.pop();
 * minStack.top();      --> 返回 2.
 * minStack.getMin();   --> 返回 -2.
 */

/**
 * 测试用例:["MinStack","push","push","push","getMin","pop","top","getMin"]
 * [[],[-2],[2],[-3],[],[],[],[]]
 * 测试结果:[null,null,null,null,-3,null,-2,-3]
 * 期望结果:[null,null,null,null,-3,null,2,-2]
 */
public class LCR147Todo {
    public static void main(String[] args) {
        String[] strs = {"MinStack", "push", "push", "push", "getMin", "pop", "top", "getMin"};
        int[][] ints = {{}, {-2}, {2}, {-3}, {}, {}, {}, {}};

        LCR147Todo minStack = new LCR147Todo();
        minStack.push(-2);
        minStack.push(2);
        minStack.push(-3);
        System.out.println(minStack.getMin());
        minStack.pop();
        System.out.println(minStack.top());
        System.out.println(minStack.getMin());

    }

    LinkedList<Integer> aList, bList, cList;
    Integer min;

    public LCR147Todo() {
        aList = new LinkedList<>();
        bList = new LinkedList<>();
        cList = new LinkedList<>();
    }

    public void push(int x) {
        // min为空直接赋值x，不为空判断x和min谁更小，赋值较小的那个
        min = Objects.isNull(min) ? x : (min > x ? x : min);
        aList.add(x);
    }

    public void pop() {
        if (Objects.equals(min, aList.removeLast())){
            bList.addAll(aList);
            aList.clear();
            min = bList.stream().min((Comparator.comparing(o -> o))).orElse(null);
        }else {
            bList.addAll(aList);
            aList.clear();
            bList.removeLast();
        }
    }

    public int top() {
        bList.addAll(Optional.of(aList).get());
        aList.clear();
        return bList.get(0);
    }

    public int getMin() {
        return min;
    }
}
